import json
import sys
import datetime

from config.config import *


def format_pval_scientific(p):
    """把小数 p 值格式化成 1×10⁻n 形式"""
    import math
    if p == 0:
        return "0"
    exponent = math.floor(math.log10(p))
    base = p / (10**exponent)
    return f"{base:.1f}×10{superscript(exponent)}"

def superscript(n):
    """整数转 Unicode 上标"""
    super_map = str.maketrans("0123456789-", "⁰¹²³⁴⁵⁶⁷⁸⁹⁻")
    return str(n).translate(super_map)


def format_metrics(metrics_dict):
    lines = []
    for key, value in metrics_dict.items():
        if key == "Confusion Matrix":
            cm = value
            lines.append(f"{key}:")
            lines.append(f"[[TN={cm[0][0]}, FP={cm[0][1]}],")
            lines.append(f" [FN={cm[1][0]}, TP={cm[1][1]}]]")
        else:
            lines.append(f"{key}: {value:.4f}")
    return "\n".join(lines)

def jr(path):
    with open(path, "r") as f:
        return json.load(f)

def jw(path,content):
    md(opd(path))
    with open(path, "w") as f:
        json.dump(content, f, indent=4)

def done(path):
    fw(path,'done')

def fw(path, content):
    md(opd(path))
    with open(path, 'w') as f:
        if isinstance(content, list):
            for line in content:
                f.write(str(line) + '\n')  # 把列表每项写成一行，自动转字符串
        else:
            f.write(str(content))

def opd(path):
    return os.path.dirname(path)

def ope(path):
   return os.path.exists(path)

def md(*args):
    os.makedirs(*args,exist_ok=True)

def ol(dir_path):
    return [f for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f))]


class Logger(object):
    def __init__(self, filename=opj(base_path,"output.txt")):
        self.terminal = sys.stdout  # 保留原本的控制台输出
        os.makedirs(os.path.dirname(filename), exist_ok=True)  # ✅ 创建目录
        self.log = open(filename, "w", encoding='utf-8')

    def write(self, message):
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.terminal.write(message)
        self.log.write(f"[{timestamp}] {message}")

    def flush(self):
        self.terminal.flush()
        self.log.flush()



def run_method_by_name(obj, method_name, *args, **kwargs):
    """通过方法名动态调用对象方法"""
    if hasattr(obj, method_name):
        method = getattr(obj, method_name)
        if callable(method):
            return method(*args, **kwargs)
        else:
            raise TypeError(f"{method_name} is not callable.")
    else:
        raise AttributeError(f"Method '{method_name}' not found in {obj.__class__.__name__}")